home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / VIEWERS / X11 / XLOADIMG.TAR / xpixmap.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  6KB  |  250 lines

  1. /* xpixmap.c:
  2.  *
  3.  * XPixMap format file read and identify routines.  these can handle any
  4.  * "format 1" XPixmap file with up to BUFSIZ - 1 chars per pixel.  it's
  5.  * not nearly as picky as it might be.
  6.  *
  7.  * unlike most image loading routines, this is X specific since it
  8.  * requires X color name parsing.  to handle this we have global X
  9.  * variables for display and screen.  it's ugly but it keeps the rest
  10.  * of the image routines clean.
  11.  *
  12.  * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  13.  * copyright information.
  14.  */
  15.  
  16. #include "copyright.h"
  17. #include "xloadimage.h"
  18.  
  19. /* SUPPRESS 530 */
  20. /* SUPPRESS 560 */
  21.  
  22. #if defined(SYSV) || defined(VMS)
  23. #include <string.h>
  24. #define rindex strrchr
  25. #else
  26. char *rindex();
  27. #endif
  28.  
  29. extern Display *Disp; /* X display, null if in "identify" mode */
  30. extern int      Scrn; /* X screen number */
  31.  
  32. #define XPM_FORMAT 1
  33.  
  34. static void corrupted(fullname, zf)
  35.      char  *fullname;
  36.      ZFILE *zf;
  37. {
  38.   zclose(zf);
  39.   printf("%s: X Pixmap file is corrupted\n", fullname);
  40.   exit(1);
  41. }
  42.  
  43. Image *xpixmapLoad(fullname, name, verbose)
  44.      char         *fullname, *name;
  45.      unsigned int  verbose;
  46. { ZFILE         *zf;
  47.   char           buf[BUFSIZ];
  48.   char           what[BUFSIZ];
  49.   char          *p;
  50.   char          *imagetitle;
  51.   unsigned int   value;
  52.   unsigned int   format;  /* image format */
  53.   unsigned int   w, h;    /* image dimensions */
  54.   unsigned int   cpp;     /* chars per pixel */
  55.   unsigned int   ncolors; /* number of colors */
  56.   unsigned int   depth;   /* depth of image */
  57.   char         **ctable;  /* color table */
  58.   Image         *image;
  59.   XColor         xcolor;
  60.   unsigned int   a, b, x, y;
  61.   int            c;
  62.   byte          *dptr;
  63.  
  64.   if (! (zf= zopen(fullname)))
  65.     return(NULL);
  66.  
  67.   /* read #defines until we have all that are necessary or until we
  68.    * get an error
  69.    */
  70.  
  71.   format= w= h= ncolors= 0;
  72.   for (;;) {
  73.     if (! zgets((byte *)buf, BUFSIZ - 1, zf)) {
  74.       zclose(zf);
  75.       return(NULL);
  76.     }
  77.     if (!strncmp(buf, "#define", 7)) {
  78.       if (sscanf(buf, "#define %s %d", what, &value) != 2) {
  79.     zclose(zf);
  80.     return(NULL);
  81.       }
  82.       if (! (p= rindex(what, '_')))
  83.     p= what;
  84.       else
  85.     p++;
  86.       if (!strcmp(p, "format"))
  87.     format= value;
  88.       else if (!strcmp(p, "width"))
  89.     w= value;
  90.       else if (!strcmp(p, "height"))
  91.     h= value;
  92.       else if (!strcmp(p, "ncolors"))
  93.     ncolors= value;
  94.  
  95.       /* this one is ugly
  96.        */
  97.  
  98.       else if (!strcmp(p, "pixel")) { /* this isn't pretty but it works */
  99.     if (p == what)
  100.       continue;
  101.     *(--p)= '\0';
  102.     if (!(p= rindex(what, '_')) || (p == what) || strcmp(++p, "per"))
  103.       continue;
  104.     *(--p)= '\0';
  105.     if (!(p= rindex(what, '_')))
  106.       p= what;
  107.     if (strcmp(++p, "chars"))
  108.       continue;
  109.     cpp= value;
  110.       }
  111.     }
  112.     else if ((sscanf(buf, "static char * %s", what) == 1) &&
  113.          (p= rindex(what, '_')) && !strcmp(++p, "colors[]"))
  114.       break;
  115.   }
  116.  
  117.   if ((format != XPM_FORMAT) || !w || !h || !ncolors || !cpp) {
  118.     zclose(zf);
  119.     return(NULL);
  120.   }
  121.  
  122.   if (p= rindex(what, '_')) {     /* get the name in the image if there is */
  123.     *p= '\0';                     /* one */
  124.     imagetitle= dupString(what);
  125.   }
  126.   else {
  127.     p= what;
  128.     imagetitle= dupString(name);
  129.   }
  130.  
  131.   if (verbose)
  132.     printf("%s is a %dx%d X Pixmap image with %d colors titled '%s'\n",
  133.        name, w, h, ncolors, imagetitle);
  134.  
  135.   for (depth= 1, value= 2; value < ncolors; value <<= 1, depth++)
  136.     ;
  137.   image= newRGBImage(w, h, depth);
  138.   image->rgb.used= ncolors;
  139.   image->title= dupString(imagetitle);
  140.  
  141.   /* read the colors array and build the image colormap
  142.    */
  143.  
  144.   ctable= (char **)lmalloc(sizeof(char *) * ncolors);
  145.   xcolor.flags= DoRed | DoGreen | DoBlue;
  146.   for (a= 0; a < ncolors; a++) {
  147.  
  148.     /* read pixel value
  149.      */
  150.  
  151.     *(ctable + a)= (char *)lmalloc(cpp);
  152.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  153.       ;
  154.     if (c == EOF)
  155.       corrupted(fullname, zf);
  156.     for (b= 0; b < cpp; b++) {
  157.       if ((c= zgetc(zf)) == '\\')
  158.     c= zgetc(zf);
  159.      if (c == EOF)
  160.     corrupted(fullname, zf);
  161.       *(*(ctable + a) + b)= (char)c;
  162.     }
  163.     if (((c= zgetc(zf)) == EOF) || (c != '"'))
  164.       corrupted(fullname, zf);
  165.  
  166.     /* read color definition and parse it
  167.      */
  168.  
  169.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  170.       ;
  171.     if (c == EOF)
  172.       corrupted(fullname, zf);
  173.     for (b= 0; ((c= zgetc(zf)) != EOF) && (c != '"'); b++) {
  174.       if (c == '\\')
  175.     c= zgetc(zf);
  176.       if (c == EOF)
  177.     corrupted(fullname, zf);
  178.       buf[b]= (char)c;
  179.     }
  180.     buf[b]= '\0';
  181.  
  182.     if (Disp) {
  183.       if (! XParseColor(Disp, DefaultColormap(Disp, Scrn), buf, &xcolor)) {
  184.     printf("%s: %s: Bad color name\n", fullname, buf);
  185.     exit(1);
  186.       }
  187.       *(image->rgb.red + a)= xcolor.red;
  188.       *(image->rgb.green + a)= xcolor.green;
  189.       *(image->rgb.blue + a)= xcolor.blue;
  190.     }
  191.   }
  192.  
  193.   for (;;) {
  194.     if (! zgets((byte *)buf, BUFSIZ - 1, zf))
  195.       corrupted(fullname, zf);
  196.     if (sscanf(buf, "static char * %s", what) == 1)
  197.       break;
  198.   }
  199.  
  200.   if (p= rindex(what, '_'))
  201.     p++;
  202.   else
  203.     p= what;
  204.   if (strcmp(p, "pixels[]"))
  205.     corrupted(fullname, zf);
  206.  
  207.   /* read in image data
  208.    */
  209.  
  210.   dptr= image->data;
  211.   for (y= 0; y < h; y++) {
  212.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  213.       ;
  214.     for (x= 0; x < w; x++) {
  215.       for (a= 0; a < cpp; a++) {
  216.     if ((c= zgetc(zf)) == '\\')
  217.       c= zgetc(zf);
  218.     if (c == EOF)
  219.       corrupted(fullname, zf);
  220.     buf[a]= (char)c;
  221.       }
  222.       for (a= 0; a < ncolors; a++)
  223.     if (!strncmp(*(ctable + a), buf, cpp))
  224.       break;
  225.       if (a == ncolors) { /* major uncool */
  226.     zclose(zf);
  227.     printf("%s: Pixel data doesn't match color data\n", fullname);
  228.     exit(1);
  229.       }
  230.       valToMem((unsigned long)a, dptr, image->pixlen);
  231.       dptr += image->pixlen;
  232.     }
  233.     if ((c= zgetc(zf)) != '"')
  234.       corrupted(fullname, zf);
  235.   }
  236.   zclose(zf);
  237.   return(image);
  238. }
  239.  
  240. int xpixmapIdent(fullname, name)
  241.      char *fullname, *name;
  242. { Image *image;
  243.  
  244.   if (image= xpixmapLoad(fullname, name, (unsigned int)1)) {
  245.     freeImage(image);
  246.     return(1);
  247.   }
  248.   return(0);
  249. }
  250.